﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mogre;
using Mogre.TutorialFramework;

namespace ProjetInfoMogre
{
	public class Robot : Entite
	{
		private bool attentionAttaqueStatue = false;
        private bool destinationEchape = false;
		private bool jaiTue = false;
		private int attenteTue = 100; 

		public Robot(SceneManager mSceneMgr, Vector3 Vposition, Monde monde)
            : base(mSceneMgr, Vposition, monde)
        {
			 //Création de l'entité Robot
            entite = mSceneMgr.CreateEntity(name, "robot.mesh");

            //Attache du robot à son noeud
            Noeud = mSceneMgr.RootSceneNode.CreateChildSceneNode(name + "Node", Vposition);
            Noeud.AttachObject(entite);
            entite.CastShadows = true;

			// donne une première destination au robot
			donneDestinationAleatoire();
        }

		public override void vit(float time)
		{
            // stratégie de fuite des robots lorsque la statue attaque 

			walk(time);
			detection();
			tueOgre();
			if (attentionAttaqueStatue)
            {
                if (!destinationEchape)
                {
                    mDistanceRestante = 0f;
                }
            }
			if (jaiTue)
			{
				if (attenteTue > 0)
					attenteTue--;
				else
				{
					jaiTue = false;
					attenteTue = 100; 
				}

			}

            
		}

		#region Actions du robot

		public override void walk(float time) // vers une destination
		{
			if (!mWalking) // si le robot ne marhe pas encore
			{
				// on lance l'animation et on signale qu'il marche
				animation = entite.GetAnimationState("Walk");
				animation.Loop = true;
				animation.Enabled = true;
				animation.AddTime(time);
				mWalking = true;

			}
			else //si le robot marche
			{
				if (mDistanceRestante > 0.0f)// si il n'est pas arrivé a sa destination
				{
					
						float distanceParcouru = mWalkSpeed * time; // le distance que le robot vient de parcourir est sa vitesse*le temps pendant lequel il veint de marcher

						//depalcement
						Noeud.Translate(mDirection * distanceParcouru);

						// on met a jour la distance qu'il lui reste a parcourir pour atteindre sa destination
						mDistanceRestante -= distanceParcouru;

						// Rotation 
						Vector3 src = Noeud.Orientation * Vector3.UNIT_X;
						if ((1.0f + src.DotProduct(mDirection)) < 0.0001f)
						{
							Noeud.Yaw(180.0f);
						}
						else
						{
							Quaternion quat = src.GetRotationTo(mDirection);
							Noeud.Rotate(quat);
						}

						animation.AddTime(time);
					
				}

                else if (attentionAttaqueStatue)
                {
                        mDestination = new Vector3(1000 + random.Next(-500, 500), 0, -1000 + random.Next(-500, 500));
                        mDirection = mDestination - Noeud.Position;
                        mDistanceRestante = mDirection.Normalise();
                        destinationEchape = true;
                }
				else
				{
					donneDestinationAleatoire();
					destinationEchape = false;
				}
					
			}


		}
		public override void detection()
		{
			// parcourir tous la liste des ogres
				//si la distance avec un ogre est inf au perimetre de detection
						//le suivre 
							//sauf s'il est dans la statue

			foreach (Entite ogre in monde.Ogres)
			{
				Vector3 distance = ogre.Noeud.Position - this.Noeud.Position;
				float distanceF = distance.Normalise();
				Vector3 distanceStatue = ogre.Noeud.Position - monde.statueOgreNode.Position;
				float distanceStatueF = distanceStatue.Normalise();
				if (distanceF <= 100f)
				{
					if (distanceStatueF > 300f)
					{
						mDestination = new Vector3(ogre.Noeud.Position.x, ogre.Noeud.Position.y - 22, ogre.Noeud.Position.z);
						mDirection = mDestination - Noeud.Position;
						mDistanceRestante = mDirection.Normalise();
					}
					else
					{
						donneDestinationAleatoire();
					}
				}					
			}
		}
		public void tueOgre()
        {
			if (!jaiTue)
			{
				// parcourir tous la liste des ogres
				//si la distance avec un ogre est inf au perimetre d'action
				List<Ogre> ogresMorts = new List<Ogre>();
				foreach (Ogre ogre in monde.Ogres)
				{
					Vector3 distance = ogre.Noeud.Position - this.Noeud.Position;
					float distanceF = distance.Normalise();
					if (distanceF <= 25f)
					{
						if (ogre.PorteCube)
						{
							ogre.PorteCube = false;
							ogre.Noeud.RemoveChild(ogre.MonCube);
							ogre.PorteCube = false;
						}
						else
						{
							ogresMorts.Add(ogre);
						}
						jaiTue = true;
					}
				}
				foreach (Ogre ogreASuppr in ogresMorts)
				{
					ogreASuppr.Noeud.Parent.RemoveChild(ogreASuppr.Noeud);
					monde.Ogres.Remove(ogreASuppr);
				}
			}

        }

		#endregion


		#region Methodes annexes
		protected void donneDestinationAleatoire()
		{
			float distanceF;
			do
			{
				mDestination = new Vector3(random.Next(-1500, 1500), 0, random.Next(-1500, 1500));
				mDirection = mDestination - Noeud.Position;
				mDistanceRestante = mDirection.Normalise();

				Vector3 distance = monde.statueOgreNode.Position - mDestination;
				distanceF = distance.Normalise();

			} while (distanceF <= 300);
		}


        public bool AttentionAttaqueStatue
        {
            get { return attentionAttaqueStatue; }
            set { attentionAttaqueStatue = value; }
		}

		#endregion

	}
}
